package com.ihome.android.util;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import com.sun.mail.util.BASE64EncoderStream;

public class TripleDesUtil {
    private static final String Algorithm = "DESede"; // DESede=3EDs

    /**
     * @description 加密算法,可用 DES,DESede,Blowfish
     * @param keybyte为加密密钥，长度为24字节
     * @param src为被加密的数据缓冲区（源）
     * @return
     */
    public static byte[] encrypt3Des(byte[] keybyte, byte[] src) {
        try {
            // 生成密钥
            SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
            // 加密
            Cipher c1 = Cipher.getInstance(Algorithm);
            c1.init(Cipher.ENCRYPT_MODE, deskey);
            return c1.doFinal(src);
        } catch (java.security.NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        } catch (javax.crypto.NoSuchPaddingException e2) {
            e2.printStackTrace();
        } catch (java.lang.Exception e3) {
            e3.printStackTrace();
        }

        return null;
    }

    /**
     * @description
     * @param keybyte为加密密钥，长度为24字节
     * @param src为加密后的缓冲区
     * @return
     */
    public static byte[] decrypt3Des(byte[] keybyte, byte[] src)
        throws Exception {
        try {
            // 生成密钥
            SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
            // 解密
            Cipher c1 = Cipher.getInstance(Algorithm);
            c1.init(Cipher.DECRYPT_MODE, deskey);
            return c1.doFinal(src);
        } catch (java.security.NoSuchAlgorithmException e1) {
            throw e1;
        } catch (javax.crypto.NoSuchPaddingException e2) {
            throw e2;
        } catch (java.lang.Exception e3) {
            throw e3;
        }
    }

    public static void exampleWithIV() {
        String s = "This is a plain text.";
        try {
            Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
            byte input[] = "this is a 24 byte key !!".getBytes();
            DESedeKeySpec KeySpec = new DESedeKeySpec(input);
            SecretKeyFactory KeyFactory = SecretKeyFactory.getInstance("DESede");
            SecretKey key = KeyFactory.generateSecret(KeySpec);
            byte[] iv = new byte[] {1, 2, 3, 4, 5, 6, 7, 8};
            IvParameterSpec ivSpec = new IvParameterSpec(iv);
            cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
            byte[] outText = cipher.doFinal(s.getBytes());
            System.err.println(new String(BASE64EncoderStream.encode(outText)).trim());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @description 加密方法
     * @param key
     * @param str
     * @return
     */
    public static String encode(String key, String str) {
        String afterEncry = null;
        try {
            // 密码长度补到24位长度
            while (key.length() != 24) {
                key = key + "0";
            }
            byte[] keyBytes = key.getBytes();
            byte[] src = str.getBytes();

            byte[] encryToken = TripleDesUtil.encrypt3Des(keyBytes, src);
            afterEncry = StringUtils.encodeHex(encryToken);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return afterEncry;
    }
    
    /**
     * @description 解密方法
     * @param key
     * @param str
     * @return
     */
    public static String decrypt(String key, String str) {
    	String afterEncry = null;
    	try {
    		// 密码长度补到24位长度
    		while (key.length() != 24) {
    			key = key + "0";
    		}
    		byte[] keyBytes = key.getBytes();
//    		byte[] src = str.getBytes();
			byte[] decodeHex = StringUtils.decodeHex(str);// 16进制转换为字节
    		byte[] encryToken = TripleDesUtil.decrypt3Des(keyBytes, decodeHex);
//    		afterEncry = StringUtils.encodeHex(encryToken);
    		afterEncry = new String(encryToken);
    		
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    	return afterEncry;
    }
    
}